// FrogMessageBox.h : Declaration of the CFrogMessageBox

#pragma once

#include "resource.h"       // main symbols

#include <atlhost.h>

// CFrogMessageBox
class CFrogMessageBox : 
	public CDialogImpl<CFrogMessageBox>
{
public:

	HBITMAP m_hBmpInfo;
	HBITMAP m_hBmpWarn;
	HBITMAP m_hBmpError;
	HBITMAP m_hBmpQuestion;

	CFrogMessageBox(LPCTSTR lpText, LPCTSTR lpCaption, UINT uType):
		m_hBmpInfo(NULL),
		m_hBmpWarn(NULL),
		m_hBmpError(NULL),
		m_hBmpQuestion(NULL)
	{
		m_lpText = lpText;
		m_lpCaption = lpCaption;
		m_uType = uType & 0x0f;
		m_uIcon = uType & 0xf0;

		m_hInstance = _AtlBaseModule.GetResourceInstance();

		m_hDisplayFont = CreateFont(-12, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, OEM_CHARSET,
			OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
			DEFAULT_PITCH | FF_DONTCARE, L"Tahoma");		
		
		m_hBmpInfo = (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(IDB_BITMAP_FROG_INFO), IMAGE_BITMAP, 0, 0, 0);
		m_hBmpWarn = (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(IDB_BITMAP_FROG_WARN), IMAGE_BITMAP, 0, 0, 0);
		m_hBmpError = (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(IDB_BITMAP_FROG_ERROR), IMAGE_BITMAP, 0, 0, 0);
		m_hBmpQuestion= (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(IDB_BITMAP_FROG_QUESTION), IMAGE_BITMAP, 0, 0, 0);
	}

	~CFrogMessageBox()
	{
		if (m_hDisplayFont)
		{
			DeleteObject(m_hDisplayFont);
			m_hDisplayFont = NULL;
		}

		if (m_hBmpInfo)
		{
			DeleteObject(m_hBmpInfo);
		}

		if (m_hBmpWarn)
		{
			DeleteObject(m_hBmpWarn);
		}


		if (m_hBmpError)
		{
			DeleteObject(m_hBmpError);
		}

		if (m_hBmpQuestion)
		{
			DeleteObject(m_hBmpQuestion);
		}
	}

	enum { IDD = IDD_DIALOG_MBOX };

	BEGIN_MSG_MAP(CFrogMessageBox)
		MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
		MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnCtlColorStatic)		
		COMMAND_HANDLER(IDOK, BN_CLICKED, OnClickedButton)
		COMMAND_HANDLER(IDCANCEL, BN_CLICKED, OnClickedButton)
		COMMAND_HANDLER(IDABORT, BN_CLICKED, OnClickedButton)
		COMMAND_HANDLER(IDRETRY, BN_CLICKED, OnClickedButton)
		COMMAND_HANDLER(IDTRYAGAIN, BN_CLICKED, OnClickedButton)
		COMMAND_HANDLER(IDCONTINUE, BN_CLICKED, OnClickedButton)
		COMMAND_HANDLER(IDNO, BN_CLICKED, OnClickedButton)
		COMMAND_HANDLER(IDYES, BN_CLICKED, OnClickedButton)
		COMMAND_HANDLER(IDIGNORE, BN_CLICKED, OnClickedButton)
	END_MSG_MAP()

	// Handler prototypes:
	//  LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	//  LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
	//  LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);

	void SetButtonPos(int nId, int pos)
	{
		RECT windowRect;
		GetClientRect(&windowRect);

		int w = 90;
		int h = 25;

		int x = windowRect.right - windowRect.left - w - 10 - (pos * (w + 10));
		int y = windowRect.bottom - windowRect.top - h - 10;

		HWND hwndButton = GetDlgItem(nId);
		::SetWindowPos(hwndButton, HWND_BOTTOM, x, y, w, h, SWP_NOZORDER);
	}

	void SetDefaultButton(int nId)
	{
		::SendMessage(GetDlgItem(nId), (UINT)BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE); 
		SendMessage((UINT)DM_SETDEFID, nId, 0);
	}

	LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		HWND pictureBox = GetDlgItem(IDC_STATIC_FROG);

		switch (m_uIcon)
		{
		case MB_ICONINFORMATION:
			{
				SendMessage(pictureBox, (UINT)STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)m_hBmpInfo);  
			}
			break;
		case MB_ICONWARNING:
			{
				SendMessage(pictureBox, (UINT)STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)m_hBmpWarn);  
			}
			break;
		case MB_ICONERROR:
			{
				SendMessage(pictureBox, (UINT)STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)m_hBmpError);  
			}
			break;
		case MB_ICONQUESTION:
			{
				SendMessage(pictureBox, (UINT)STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)m_hBmpQuestion);  
			}
			break;
		default:
			{
				SendMessage(pictureBox, (UINT)STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)m_hBmpInfo);  
			}
			break;
		}			

		bHandled = TRUE;

		SetWindowSize();

		SetDlgItemText(IDC_STATIC_TITLE, m_lpText);
		SetWindowText(m_lpCaption);

		switch (m_uType)
		{
		case MB_OK:
			{

				::DestroyWindow(GetDlgItem(IDCANCEL));
				::DestroyWindow(GetDlgItem(IDABORT));
				::DestroyWindow(GetDlgItem(IDRETRY));
				::DestroyWindow(GetDlgItem(IDIGNORE));
				::DestroyWindow(GetDlgItem(IDYES));
				::DestroyWindow(GetDlgItem(IDNO));
				::DestroyWindow(GetDlgItem(IDTRYAGAIN));
				::DestroyWindow(GetDlgItem(IDCONTINUE));

				SetDefaultButton(IDOK);
				SetButtonPos(IDOK,0);
			}
			break;
		case MB_OKCANCEL:
			{
				::DestroyWindow(GetDlgItem(IDABORT));
				::DestroyWindow(GetDlgItem(IDRETRY));
				::DestroyWindow(GetDlgItem(IDIGNORE));
				::DestroyWindow(GetDlgItem(IDYES));
				::DestroyWindow(GetDlgItem(IDNO));
				::DestroyWindow(GetDlgItem(IDTRYAGAIN));
				::DestroyWindow(GetDlgItem(IDCONTINUE));

				SetDefaultButton(IDOK);
				SetButtonPos(IDCANCEL,0);
				SetButtonPos(IDOK,1);				
			}
			break;
		case MB_ABORTRETRYIGNORE:
			{
				::DestroyWindow(GetDlgItem(IDOK));
				::DestroyWindow(GetDlgItem(IDCANCEL));
				::DestroyWindow(GetDlgItem(IDYES));
				::DestroyWindow(GetDlgItem(IDNO));
				::DestroyWindow(GetDlgItem(IDTRYAGAIN));
				::DestroyWindow(GetDlgItem(IDCONTINUE));

				SetDefaultButton(IDRETRY);
				SetButtonPos(IDIGNORE,0);
				SetButtonPos(IDRETRY,1);
				SetButtonPos(IDABORT,2);				
			}
			break;

		case MB_YESNO:
			{
				::DestroyWindow(GetDlgItem(IDOK));
				::DestroyWindow(GetDlgItem(IDCANCEL));
				::DestroyWindow(GetDlgItem(IDABORT));
				::DestroyWindow(GetDlgItem(IDRETRY));
				::DestroyWindow(GetDlgItem(IDIGNORE));
				::DestroyWindow(GetDlgItem(IDTRYAGAIN));
				::DestroyWindow(GetDlgItem(IDCONTINUE));

				SetDefaultButton(IDYES);
				SetButtonPos(IDNO,0);
				SetButtonPos(IDYES,1);
			}
			break;

		case MB_YESNOCANCEL:
			{
				::DestroyWindow(GetDlgItem(IDOK));
				::DestroyWindow(GetDlgItem(IDABORT));
				::DestroyWindow(GetDlgItem(IDRETRY));
				::DestroyWindow(GetDlgItem(IDIGNORE));
				::DestroyWindow(GetDlgItem(IDTRYAGAIN));
				::DestroyWindow(GetDlgItem(IDCONTINUE));

				SetDefaultButton(IDYES);
				SetButtonPos(IDCANCEL,0);
				SetButtonPos(IDNO,1);
				SetButtonPos(IDYES,2);
			}
			break;
		case MB_RETRYCANCEL:
			{
				::DestroyWindow(GetDlgItem(IDOK));
				::DestroyWindow(GetDlgItem(IDABORT));
				::DestroyWindow(GetDlgItem(IDIGNORE));
				::DestroyWindow(GetDlgItem(IDYES));
				::DestroyWindow(GetDlgItem(IDNO));
				::DestroyWindow(GetDlgItem(IDTRYAGAIN));
				::DestroyWindow(GetDlgItem(IDCONTINUE));

				SetDefaultButton(IDCANCEL);
				SetButtonPos(IDCANCEL,0);
				SetButtonPos(IDRETRY,1);
			}
			break;

		case MB_CANCELTRYCONTINUE:
			{
				::DestroyWindow(GetDlgItem(IDOK));
				::DestroyWindow(GetDlgItem(IDABORT));
				::DestroyWindow(GetDlgItem(IDIGNORE));
				::DestroyWindow(GetDlgItem(IDYES));
				::DestroyWindow(GetDlgItem(IDNO));
				::DestroyWindow(GetDlgItem(IDRETRY));

				SetDefaultButton(IDCONTINUE);
				SetButtonPos(IDCONTINUE,0);
				SetButtonPos(IDTRYAGAIN,1);
				SetButtonPos(IDCANCEL,2);
			}
			break;
		}

		return 1;  // Let the system set the focus
	}

	LRESULT OnCtlColorStatic(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		bHandled = true;

		if (::GetDlgCtrlID((HWND)lParam) == IDC_STATIC_TITLE)
		{				
			SetBkMode((HDC)wParam, TRANSPARENT);				
			return (BOOL)GetStockObject(NULL_BRUSH);
		}
		else
		{
			return FALSE;
		}
	}	

	LRESULT CFrogMessageBox::OnClickedButton(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
	{
		EndDialog(wID);
		return 0;
	}

private:
	HINSTANCE m_hInstance;
	HFONT m_hDisplayFont;
	LPCTSTR m_lpText;
	LPCTSTR m_lpCaption;
	UINT m_uType;
	UINT m_uIcon;

	void InitWhiteBar(int lineCount = 0)
	{
		RECT windowRect;
		GetWindowRect(&windowRect);

		int w = windowRect.right - windowRect.left + 10;
		int h = 90;
		int x = -5;
		int y = -5;

		HWND hwndTitle = GetDlgItem(IDC_STATIC_TITLE);

		if (lineCount > 3)
		{
			h = h + 13 * (lineCount - 3);

			RECT titleRect;
			::GetWindowRect(hwndTitle, &titleRect);
						
			int w1 = titleRect.right - titleRect.left;
			int h1 = titleRect.bottom - titleRect.top;
			int x1 = titleRect.left;
			int y1 = titleRect.top;

			POINT point;
			point.x = x1;
			point.y = y1;

			ScreenToClient(&point);

			x1 = point.x;
			y1 = point.y;
			
			h1 = h1 + 13 * (lineCount - 3);
			::SetWindowPos(hwndTitle, HWND_BOTTOM, x1, y1, w1, h1, SWP_NOZORDER);
		}

		HWND hwndWhiteRect = GetDlgItem(IDC_STATIC_WHITE_RECT);
		::SetWindowPos(hwndWhiteRect, HWND_BOTTOM, x, y, w, h, SWP_NOZORDER);
		SendMessage(hwndTitle, WM_SETFONT, (WPARAM)m_hDisplayFont, TRUE);
	}

	int GetTitleLineCount()
	{
		wstring text = m_lpText;
		int lineCount = 1;

		int charCount = 0;

		for (int i=0; i<text.length(); i++)
		{
			charCount++;

			if (charCount > 50 || text.at(i) == L'\n')
			{
				lineCount++;
				charCount = 0;
			}
		}

		return lineCount;
	}

	void SetWindowSize()
	{
		RECT windowRect;
		GetWindowRect(&windowRect);

		int w = windowRect.right - windowRect.left;
		int h = windowRect.bottom - windowRect.top;
		int x = windowRect.left;
		int y = windowRect.top;		
		
		int new_w = 460;		
		x = x + ((w - new_w) / 2);

		int lineCount = GetTitleLineCount();

		if (lineCount > 3)
		{
			h = h + 13 * (lineCount - 3);
		}

		SetWindowPos(HWND_BOTTOM, x, y, new_w, h, SWP_NOZORDER);

		InitWhiteBar(lineCount);
	}
};

static int FrogMessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
{
	CFrogMessageBox frogMessageBox(lpText,lpCaption, uType);
	return (int)frogMessageBox.DoModal(hWnd);
}